﻿$import( "SmitearWebGL.Programs.AbstractProgram" );

SmitearWebGL.Programs.LightPrePass.ShadowVolProgram = SmitearWebGL.Programs.AbstractProgram.extend(
{
	/******** constructor ********/
	
	init : function()
	{
		this._super();
		this._registClass( "SmitearWebGL.Programs.LightPrePass.ShadowVolProgram" );
	}
	,
	
	/******** public method ********/
	
	activeUniform : function( renderableObject )
	{
		renderableObject.glUniform( SmitearWebGL.ShaderUniform.worldViewMatrix, this._shader );
		renderableObject.glUniform( SmitearWebGL.ShaderUniform.projectionMatrix, this._shader );
		renderableObject.glUniform( SmitearWebGL.ShaderUniform.normalViewMatrix, this._shader );
		
		this.context.gl.uniform1f( this._shader.uniforms.uFarClip.location, renderableObject.getScene().getRenderSession().farClip - 10.0 );
		
		return SmitearWebGL.Core.HResult.SUCCESS;
	}
	,
	
	/******** private method ********/
	
	_generateVertexShaderStr : function()
	{
		this._super();
		
		var vertStr = [];
		vertStr.push( "uniform mat4 uWorldViewMatrix;\n" );
		vertStr.push( "uniform mat4 uNormalViewMatrix;\n" );
		vertStr.push( "uniform mat4 uProjectionMatrix;\n" );
		vertStr.push( "uniform vec3 uLightPos;\n" );
		vertStr.push( "uniform float uFarClip;\n" );
		vertStr.push( "attribute vec3 " + SmitearWebGL.Resources.Buffer.AttribLocation.POSITION +";\n" );
		vertStr.push( "attribute vec3 " + SmitearWebGL.Resources.Buffer.AttribLocation.NORMAL +";\n" );
		vertStr.push( "void main()\n" );
		vertStr.push( "{\n" );
		vertStr.push( "vec4 posView = uWorldViewMatrix * vec4(" + SmitearWebGL.Resources.Buffer.AttribLocation.POSITION +", 1.0);\n" );
		vertStr.push( "vec3 n = normalize((uNormalViewMatrix * vec4(" + SmitearWebGL.Resources.Buffer.AttribLocation.NORMAL +", 0.0)).xyz);\n" );
		vertStr.push( "vec3 lightVecView = posView.xyz - uLightPos;\n" );
		vertStr.push( "if(dot(- normalize(lightVecView), n) < 0.0)\n" );
		vertStr.push( "{\n" );
		vertStr.push( "if(posView.z < uLightPos.z)\n" );
		vertStr.push( "{\n" );
		vertStr.push( "vec3 t = lightVecView * (- uFarClip - posView.z) / lightVecView.z;\n" );
		vertStr.push( "posView.xyz += t.xyz;\n" );
		vertStr.push( "}\n" );
		vertStr.push( "else\n" );
		vertStr.push( "posView = vec4( lightVecView, 0.0 );\n" );
		vertStr.push( "}\n" );
		vertStr.push( "gl_Position = uProjectionMatrix * posView;\n" );
		vertStr.push( "}\n" );
		
		return vertStr.join("");
	}
	,
	_generateFragmentShaderStr : function()
	{
		this._super();
		
		var fragStr = [];
		fragStr.push( "#ifdef GL_ES\n" );
		fragStr.push( "precision highp float;\n" );
		fragStr.push( "#endif\n" );
		fragStr.push( "uniform vec3 uLightColor;\n" );
		fragStr.push( "void main()\n" );
		fragStr.push( "{\n" );
		fragStr.push( "gl_FragColor = vec4(uLightColor.rgb, 0.2);\n" );
		fragStr.push( "}\n" );
		
		return fragStr.join("");
	}
}
);